
#include <BLabel>
#include <BButtonGroup>
#include <BHBoxLayout>
#include <BVBoxLayout>
#include <BGroupBox>
#include <BStyle>
#include <BSpacer>
#include <BPainter>
#include <BColorDialog>

#include "ReplaceDialog.h"

ReplaceDialog::ReplaceDialog(BWidget* parent) : BDialog(parent)
{
	this->setTitle("Replace");

	_colorReplacer = new ColorReplacer();
	_colorPicker = new ColorPicker();

	BHBoxLayout* colorLayout = new BHBoxLayout();
	{
		BLabel* colorLabel = new BLabel("origin-color");
		_colorButton = new BButton(Graph_Square_Fill);

		_colorSpacer = new BSpacer(20, Policy_Fixed, Policy_Fixed);

		_colorPickButton = new BButton("pick");
		_colorPickButton->setForm(Form_IconAlone);
		_colorPickButton->setCheckable(true);

		colorLayout->addWidget(colorLabel);
		colorLayout->addWidget(_colorButton);
		colorLayout->addSpring();
		colorLayout->addSpacer(_colorSpacer);
		colorLayout->addWidget(_colorPickButton);
	}

	BVBoxLayout* toleranceLayout = new BVBoxLayout();
	{
		BLabel* toleranceLabel = new BLabel("tolerance");
		_toleranceSlider = new BSlider(0, 255);
		_toleranceSpinBox = new BSpinBox(0, 255);

		BHBoxLayout* hlayout = new BHBoxLayout();
		hlayout->addWidget(toleranceLabel);
		hlayout->addSpring();
		hlayout->addWidget(_toleranceSpinBox);

		toleranceLayout->addLayout(hlayout);
		toleranceLayout->addWidget(_toleranceSlider);
	}

	BHBoxLayout* targetColorLayout = new BHBoxLayout();
	{
		BLabel* targetColorLabel = new BLabel("target-color");
		_targetColorButton = new BButton(Graph_Square_Fill);

		_targetColorSpacer = new BSpacer(20);

		_targetColorPickButton = new BButton("pick");
		_targetColorPickButton->setForm(Form_IconAlone);
		_targetColorPickButton->setCheckable(true);

		targetColorLayout->addWidget(targetColorLabel);
		targetColorLayout->addWidget(_targetColorButton);
		targetColorLayout->addSpring();
		targetColorLayout->addSpacer(_targetColorSpacer);
		targetColorLayout->addWidget(_targetColorPickButton);
	}

	BGroupBox* regionGroupBox = new BGroupBox("Apply Region");
	BButtonGroup* regionButtonGroup = new BButtonGroup();
	{
		_constituencyRadioBox = new BRadioBox("constituency");
		_wholeLayersRadioBox = new BRadioBox("wholeLayers");

		BVBoxLayout* vlayout = new BVBoxLayout(regionGroupBox);
		vlayout->addWidget(_constituencyRadioBox);
		vlayout->addWidget(_wholeLayersRadioBox);

		regionButtonGroup->addButton(_constituencyRadioBox);
		regionButtonGroup->addButton(_wholeLayersRadioBox);
		regionGroupBox->setAsset(regionButtonGroup);
	}

	BVBoxLayout* vlayout = new BVBoxLayout(this);
	vlayout->addLayout(colorLayout);
	vlayout->addLayout(toleranceLayout);
	vlayout->addSpacer(6);
	vlayout->addLayout(targetColorLayout);
	vlayout->addSpacer(6);
	vlayout->addWidget(regionGroupBox);

	BHBoxLayout* bottomLayout = new BHBoxLayout();
	{
		_applyButton = new BButton("apply");
		_resetButton = new BButton("reset");
		_loadRecordButton = new BButton("load-record");
		_saveRecordButton = new BButton("save-record");
		bottomLayout->addWidget(_loadRecordButton);
		bottomLayout->addWidget(_saveRecordButton);
		bottomLayout->addSpring();
		bottomLayout->addWidget(_resetButton);
		bottomLayout->addWidget(_applyButton);
	}
	this->setLayout(bottomLayout, Part_Bottom);

	connect(_colorPickButton, Signal_Toggled, &ReplaceDialog::slotColorPickButtonToggled);
	connect(_targetColorPickButton, Signal_Toggled, &ReplaceDialog::slotTargetColorPickButtonToggled);
	connect(_colorButton, Signal_Clicked, &ReplaceDialog::slotColorButtonClicked);
	connect(_targetColorButton, Signal_Clicked, &ReplaceDialog::slotTargetColorButtonClicked);
	connect(_toleranceSlider, Signal_Sliding, &ReplaceDialog::slotToleranceSliding);
	connect(_toleranceSpinBox, Signal_EditFinished, &ReplaceDialog::slotTolenranceEditFinished);
	connect(_toleranceSpinBox, Signal_ValueChanged, &ReplaceDialog::slotTolenranceChanged);
	connect(regionButtonGroup, Signal_Checked, &ReplaceDialog::slotRegionButtonGroupChecked);
	connect(_applyButton, Signal_Clicked, &ReplaceDialog::slotApplyButtonClicked);
	connect(_resetButton, Signal_Clicked, &ReplaceDialog::slotResetButtonClicked);
	connect(_loadRecordButton, Signal_Clicked, &ReplaceDialog::slotLoadRecordButtonClicked);
	connect(_saveRecordButton, Signal_Clicked, &ReplaceDialog::slotSaveRecordButtonClicked);

	connect(_colorPicker, "pick-finished", &ReplaceDialog::slotColorPickerFinished);
	connect(_colorPicker, "pick-color", &ReplaceDialog::slotColorPickerPicked);
	connect(_colorPicker, Signal_Detached, &ReplaceDialog::slotColorPickerDetached);

	connect(_colorReplacer, "pixels-catched", &ReplaceDialog::slotPixelsCatched);
}
ReplaceDialog::~ReplaceDialog()
{

}

void ReplaceDialog::slotColorPickButtonToggled(BObject* object, const BValue& value)
{
	_colorPicker->setAsset(_colorSpacer);
	if (value)
		_colorReplacer->addChild(_colorPicker);
	else
		_colorReplacer->removeChild(_colorPicker);
}
void ReplaceDialog::slotTargetColorPickButtonToggled(BObject* object, const BValue& value)
{
	_colorPicker->setAsset(_targetColorSpacer);
	if (value)
		_colorReplacer->addChild(_colorPicker);
	else
		_colorReplacer->removeChild(_colorPicker);
}
void ReplaceDialog::slotColorPickerPicked(BObject* object, const BValue& value)
{
	this->fresh();
}
void ReplaceDialog::slotColorPickerFinished(BObject* object, const BValue& value)
{
	BColor color = value;
	if (_colorPicker->asset() == _colorSpacer)
	{
		_colorButton->setColor(color);
		_colorReplacer->setMatchColor(color);
	}
	if (_colorPicker->asset() == _targetColorSpacer)
	{
		_targetColorButton->setColor(color);
		_colorReplacer->setTargetColor(color);
	}
	_colorPicker->detach();
	_colorPicker->setAsset(BValue());
}
void ReplaceDialog::slotColorPickerDetached(BObject* object, const BValue& value)
{
	_colorPicker->setAsset(BValue());
	_colorSpacer->setAsset(BValue());
	_targetColorSpacer->setAsset(BValue());
	_colorPickButton->setChecked(false);
	_targetColorPickButton->setChecked(false);
	this->fresh();
}

void ReplaceDialog::slotColorButtonClicked()
{
	BColor color = BColorDialog::ChooseColor(this, "Choose Origin Color", _colorButton->color());
	_colorButton->setColor(color);
	_colorReplacer->setMatchColor(color);
}
void ReplaceDialog::slotTargetColorButtonClicked(BObject* object, const BValue& value)
{
	BColor color = BColorDialog::ChooseColor(this, "Choose Target Color", _colorButton->color());
	_targetColorButton->setColor(color);
	_colorReplacer->setTargetColor(color);
}
void ReplaceDialog::slotToleranceSliding(BObject* object, const BValue& value)
{
	int tolerance = value;
	_toleranceSpinBox->setValue(value);
}
void ReplaceDialog::slotTolenranceEditFinished(BObject* object, const BValue& value)
{
	int tolerance = value;
	_toleranceSlider->setValue(value);
}
void ReplaceDialog::slotTolenranceChanged(BObject* object, const BValue& value)
{
	int tolerance = value;
	_colorReplacer->setMatchTolerance(tolerance);
}

void ReplaceDialog::slotRegionButtonGroupChecked(BObject* object, const BValue& value)
{

}
void ReplaceDialog::slotPixelsCatched(BObject* object, const BValue& value)
{
	int size = value;
	_applyButton->setEnabled(size > 0);
}
void ReplaceDialog::slotApplyButtonClicked()
{
	_colorReplacer->replace();
	_applyButton->setEnabled(false);
}
void ReplaceDialog::slotResetButtonClicked()
{

}
void ReplaceDialog::slotLoadRecordButtonClicked()
{

}
void ReplaceDialog::slotSaveRecordButtonClicked()
{

}

void ReplaceDialog::showEvent(const BEvent& event)
{
	BDialog::showEvent(event);
	emit("apply-operation", _colorReplacer);
	_colorReplacer->setMatchColor(_colorButton->color());
	_colorReplacer->setMatchTolerance(_toleranceSpinBox->value());
	_colorReplacer->setTargetColor(_targetColorButton->color());
	_colorReplacer->setOnlyConstituency(_constituencyRadioBox->checked());
}
void ReplaceDialog::hideEvent(const BEvent& event)
{
	BDialog::hideEvent(event);
	_colorReplacer->detach();
}

void ReplaceDialog::styleEvent(const BEvent& event)
{
	BDialog::styleEvent(event);
	if (const BStyle* style = this->realStyle())
	{
		_colorPickButton->setIcon(style->icon("color-pick"));
		_targetColorPickButton->setIcon(style->icon("color-pick"));

		_colorPickButton->setTips(style->text("tips-pick-origin"));
		_targetColorPickButton->setTips(style->text("tips-pick-target"));
	}
}
void ReplaceDialog::paintEvent(const BEvent& event)
{
	BDialog::paintEvent(event);
	if (_colorPicker->asset().valid())
	{
		BPainter painter(this);
		if (_colorPicker->asset() == _colorSpacer)
		{
			const BColor& color = _colorSpacer->asset();
			if (painter.setColor(color))
				painter.fillRect(_colorSpacer->rect());
		}
		if (_colorPicker->asset() == _targetColorSpacer)
		{
			const BColor& color = _targetColorSpacer->asset();
			if (painter.setColor(color))
				painter.fillRect(_targetColorSpacer->rect());
		}
	}
}
